package handlers

import (
	"context"
	"fmt"
	"ourplansystem/server/ent"
	"ourplansystem/server/ent/photo"
	"ourplansystem/server/models"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
)

// PhotoHandler 照片墙处理器
type PhotoHandler struct {
	client *ent.Client
}

// NewPhotoHandler 创建照片墙处理器
func NewPhotoHandler(client *ent.Client) *PhotoHandler {
	return &PhotoHandler{client: client}
}

// CreatePhotoRequest 创建照片请求
type CreatePhotoRequest struct {
	URL            string `json:"url"`
	Description    string `json:"description"`
	UploadUserID   int64  `json:"upload_user_id"`
}

// UpdatePhotoRequest 更新照片请求
type UpdatePhotoRequest struct {
	Description string `json:"description"`
}

// GetPhotos 获取所有未删除的照片
func (h *PhotoHandler) GetPhotos(c *fiber.Ctx) error {
	ctx := context.Background()
	photos, err := h.client.Photo.Query().
		Where(photo.DeletedAtIsNil()).
		WithUploader().
		All(ctx)
	if err != nil {
		return models.InternalServerError(c, "获取照片列表失败")
	}

	return models.Success(c, photos)
}

// GetPhoto 获取单个照片
func (h *PhotoHandler) GetPhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	id, err := strconv.ParseInt(c.Params("id"), 10, 64)
	if err != nil {
		return models.BadRequest(c, "无效的照片ID")
	}

	photo, err := h.client.Photo.Get(ctx, id)
	if err != nil {
		if ent.IsNotFound(err) {
			return models.NotFound(c, "照片不存在")
		}
		return models.InternalServerError(c, "获取照片失败")
	}

	return models.Success(c, photo)
}

// CreatePhoto 创建照片
func (h *PhotoHandler) CreatePhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	var req CreatePhotoRequest
	if err := c.BodyParser(&req); err != nil {
		return models.BadRequest(c, "请求参数错误")
	}

	if req.URL == "" {
		return models.BadRequest(c, "照片URL不能为空")
	}

	if req.UploadUserID == 0 {
		return models.BadRequest(c, "上传者ID不能为空")
	}

	builder := h.client.Photo.
		Create().
		SetURL(req.URL).
		SetUploadUserID(req.UploadUserID)

	if req.Description != "" {
		builder.SetDescription(req.Description)
	}

	photo, err := builder.Save(ctx)
	if err != nil {
		return models.InternalServerError(c, "上传照片失败")
	}

	return models.SuccessWithMessage(c, "上传成功", photo)
}

// UpdatePhoto 更新照片
func (h *PhotoHandler) UpdatePhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	id, err := strconv.ParseInt(c.Params("id"), 10, 64)
	if err != nil {
		return models.BadRequest(c, "无效的照片ID")
	}

	var req UpdatePhotoRequest
	if err := c.BodyParser(&req); err != nil {
		return models.BadRequest(c, "请求参数错误")
	}

	builder := h.client.Photo.UpdateOneID(id)

	if req.Description != "" {
		builder.SetDescription(req.Description)
	}

	photo, err := builder.Save(ctx)
	if err != nil {
		if ent.IsNotFound(err) {
			return models.NotFound(c, "照片不存在")
		}
		return models.InternalServerError(c, "更新照片失败")
	}

	return models.SuccessWithMessage(c, "更新成功", photo)
}

// DeletePhoto 软删除照片
func (h *PhotoHandler) DeletePhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	id, err := strconv.ParseInt(c.Params("id"), 10, 64)
	if err != nil {
		return models.BadRequest(c, "无效的照片ID")
	}

	// 软删除：设置 deleted_at 为当前时间
	now := time.Now()
	_, err = h.client.Photo.UpdateOneID(id).
		SetDeletedAt(now).
		Save(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return models.NotFound(c, "照片不存在")
		}
		return models.InternalServerError(c, "删除照片失败")
	}

	return models.SuccessWithMessage(c, "删除成功", nil)
}

// GetDeletedPhotos 获取所有已删除的照片（回收站）
func (h *PhotoHandler) GetDeletedPhotos(c *fiber.Ctx) error {
	ctx := context.Background()
	photos, err := h.client.Photo.Query().
		Where(photo.DeletedAtNotNil()).
		WithUploader().
		All(ctx)
	if err != nil {
		return models.InternalServerError(c, "获取已删除照片失败")
	}

	return models.Success(c, photos)
}

// RestorePhoto 恢复已删除的照片
func (h *PhotoHandler) RestorePhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	id, err := strconv.ParseInt(c.Params("id"), 10, 64)
	if err != nil {
		return models.BadRequest(c, "无效的照片ID")
	}

	// 恢复：清空 deleted_at
	_, err = h.client.Photo.UpdateOneID(id).
		ClearDeletedAt().
		Save(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return models.NotFound(c, "照片不存在")
		}
		return models.InternalServerError(c, "恢复照片失败")
	}

	return models.SuccessWithMessage(c, "恢复成功", nil)
}

// PermanentDeletePhoto 永久删除照片
func (h *PhotoHandler) PermanentDeletePhoto(c *fiber.Ctx) error {
	ctx := context.Background()
	id, err := strconv.ParseInt(c.Params("id"), 10, 64)
	if err != nil {
		return models.BadRequest(c, "无效的照片ID")
	}

	err = h.client.Photo.DeleteOneID(id).Exec(ctx)
	if err != nil {
		if ent.IsNotFound(err) {
			return models.NotFound(c, "照片不存在")
		}
		return models.InternalServerError(c, "永久删除照片失败")
	}

	return models.SuccessWithMessage(c, "永久删除成功", nil)
}

// UploadPhoto 上传照片文件
func (h *PhotoHandler) UploadPhoto(c *fiber.Ctx) error {
	ctx := context.Background()

	// 获取上传的文件
	file, err := c.FormFile("file")
	if err != nil {
		return models.BadRequest(c, "请选择要上传的图片")
	}

	// 验证文件大小（最大 50MB）
	if file.Size > 50*1024*1024 {
		return models.BadRequest(c, "图片大小不能超过50MB")
	}

	// 获取文件扩展名并验证
	ext := strings.ToLower(filepath.Ext(file.Filename))
	allowedExts := map[string]bool{
		".jpg":  true,
		".jpeg": true,
		".png":  true,
		".gif":  true,
		".webp": true,
	}
	if !allowedExts[ext] {
		return models.BadRequest(c, "只支持 jpg、png、gif、webp 格式的图片")
	}

	// 生成唯一文件名：时间戳_UUID.ext
	filename := fmt.Sprintf("%d_%s%s", time.Now().Unix(), uuid.New().String(), ext)
	savePath := filepath.Join("uploads", "photos", filename)

	// 保存文件
	if err := c.SaveFile(file, savePath); err != nil {
		return models.InternalServerError(c, "保存图片失败")
	}

	// 获取上传者ID和描述
	uploadUserID, err := strconv.ParseInt(c.FormValue("upload_user_id"), 10, 64)
	if err != nil || uploadUserID == 0 {
		return models.BadRequest(c, "上传者ID不能为空")
	}
	description := c.FormValue("description")

	// 生成访问URL
	baseURL := c.BaseURL()
	imageURL := fmt.Sprintf("%s/%s", baseURL, savePath)

	// 创建照片记录
	builder := h.client.Photo.
		Create().
		SetURL(imageURL).
		SetUploadUserID(uploadUserID)

	if description != "" {
		builder.SetDescription(description)
	}

	photo, err := builder.Save(ctx)
	if err != nil {
		return models.InternalServerError(c, "创建照片记录失败")
	}

	return models.SuccessWithMessage(c, "上传成功", photo)
}
